#pragma once

#include "../inc/ff_utils.h"

using namespace feifei;

class UtilsTest
{
private:
	int argc;
	char** argv;

public:
	UtilsTest(int _argc, char* _argv[]) { argc = _argc, argv = _argv; };
	void Test()
	{
		PrintSeperator('*');
		PrintHeader("utils test", '*');
		PrintSeperator('*');

		LOG(get_curr_path());
		LOG(get_work_path());
		LOG(get_debug_path());

		TestComplex();		INFO("");
		TestCmdLI();		INFO("");
		TestTimer();		INFO("");
		TestLog();			INFO("");
		TestDatabase();		INFO("");
		TestDataLog();		INFO("");
		TestDataDump();		INFO("");

		PrintSeperator('*');
		INFO("");
	}

	void TestCmdLI()
	{
		PrintSeperator('-');
		PrintHeader("command argument test");

		typedef enum ArgIdEnum
		{
			CMD_ARG_HELP,
			CMD_ARG_TEST
		} E_ArgId;

		CmdArgs* ca = CmdArgs::GetCmdArgs();
		ca->AddOneArg(CMD_ARG_HELP, CmdArgs::E_ValueType::String, "help", 'h', "help", "help infomation\n");
		ca->AddOneArg(CMD_ARG_TEST, CmdArgs::E_ValueType::Int, "0", 't', "test", "test enviroment and simu parameters\n");
		ca->PaserCmdArgs(argc, argv);

		int t = *(int*)ca->GetOneArg(CMD_ARG_TEST);
		LOG("cmd arg t = %d.", t);
	}
	void TestComplex()
	{
		PrintSeperator('-');
		PrintHeader("complex test");
		cplx<float> a = cplx<float>(1.0f, 2.0f);
		cplx<float> b = cplx<float>(4.0f, 5.0f);
		cplx<float> c = cplx<float>(3.0f);
		cplx<float> d;

		d = a + b;
		LOG("a + b = <%.2f, %.2f>", d.x, d.y);
		d = a * c;
		LOG("a * c = <%.2f, %.2f>", d.x, d.y);
	}
	void TestTimer()
	{
		PrintSeperator('-');
		PrintHeader("timer test");

		ffTimer tmr;
		tmr.Restart();
		ffSleepSec(1);
		ffSleepMilliSec(50);
		tmr.Stop();
		LOG("elapsed time = %.3f.", tmr.ElapsedMilliSec * 1e-3);
	}
	void TestLog()
	{
		PrintSeperator('-');
		PrintHeader("log file test");

		LOG(std::string("this is the log test."));
		WARN("print warning output %d.", 1);
		LogFile logf("utils_test");
		logf.Log("this is the log file test.");
	}
	void TestDatabase()
	{
		PrintSeperator('-');
		PrintHeader("database test");

		Database db("test_db");
		T_SaveData d;
		d.a = 1; d.b = 2.3f; d.c = 'A'; d.d = 5.67;	db.SaveRcd(d);
		d.a = 2; d.b = 3.4f; d.c = 'B'; d.d = 6.78;	db.SaveRcd(d);
		d.a = 3; d.b = 4.5f; d.c = 'C'; d.d = 7.89;	db.SaveRcd(d);
		db.LoadDbFile();
		LOG("db data size = %d", db.SaveDataMap.size());
		db.ResaveDbFile();
	}
	void TestDataLog()
	{
		PrintSeperator('-');
		PrintHeader("log data test");

		float a[128];
		cplx<float> b[128];
		uint32_t len = 128;

		for (uint32_t i = 0; i < len; i++)
		{
			a[i] = i * 0.1f;
			b[i] = cplx<float>(1.0f * i, -0.1f * i);
		}

		LogData(a, 64, "a", 32, true, 8, 8);
		LogData(b, 64, "cplx b", 32, false, 4, 2);
	}
	void TestDataDump()
	{
		PrintSeperator('-');
		PrintHeader("dump data test");

		float a[128];
		cplx<float> b[128];
		uint32_t len = 128;

		for (uint32_t i = 0; i < len; i++)
		{
			a[i] = i * 0.1f;
			b[i] = cplx<float>(1.0f * i, -0.1f * i);
		}

		DumpData(a, 128, get_debug_path() + "a.txt");
		DumpData(b, 64, get_debug_path() + "cplx-b.txt", true, 32, false, 4, 2);

		DumpMem(a, 128, get_debug_path() + "a.dat");
		DumpMem(b, 64, get_debug_path() + "cplx-b.dat", false, 32);

		float* aa = nullptr;
		cplx<float>* bb = nullptr;
		size_t ll;
		ll = LoadMem((void**)&aa, get_debug_path() + "a.dat", 32 * sizeof(float), 64 * sizeof(float));
		ll = ll / sizeof(float);
		LogData(aa, ll, "aa");
		ll = LoadMem((void**)&bb, get_debug_path() + "cplx-b.dat");
		ll = ll / sizeof(cplx<float>);
		LogData(bb, ll, "bb");
	}
};
